package io.renren.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;

/**
* @Description 线程池工具类
*/
public class ThreadPoolUtil {
    private static final Logger log = LoggerFactory.getLogger(ThreadPoolUtil.class);

    private static final int CORE_POOL_SIZE = 50;
    private static final int MAX_POOL_SIZE = 200;
    private static final int KEEP_ALIVE_TIME = 10;
    private static BlockingQueue queue = new LinkedBlockingQueue(10000);
    private static ExecutorService SERVICE = new ThreadPoolExecutor(CORE_POOL_SIZE,
            MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, queue, (r, executor) -> log.error("ThreadPoolUtil waiting queue is full!"));

    public static <T> Future<T> submitTask(Callable<T> task) {
        return SERVICE.submit(task);
    }

    public static <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
        return SERVICE.invokeAll(tasks);
    }


    public static void submitTask(Runnable task) {
        SERVICE.submit(task);
    }

    public static void shutDown(){
        SERVICE.shutdown();
    }

    public static void shutdownAndAwaitTermination() {
        SERVICE.shutdown(); // Disable new tasks from being submitted
        try {
            // Wait a while for existing tasks to terminate
            if (!SERVICE.awaitTermination(60, TimeUnit.SECONDS)) {
                SERVICE.shutdownNow(); // Cancel currently executing tasks
                // Wait a while for tasks to respond to being cancelled
                if (!SERVICE.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (InterruptedException ie) {
            // (Re-)Cancel if current thread also interrupted
            SERVICE.shutdownNow();
            // Preserve interrupt status
            Thread.currentThread().interrupt();
        }
    }

    private static void testSimpleCompletableFuture() throws Exception {
        long start = System.currentTimeMillis();
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "\t  is coming in ...");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            System.out.println(Thread.currentThread().getName() + "\t task was finished!");
        });

        // },poolExecutor);
        // 如果使用了自行创建的线程池，则使用自定义的或者特别指定的线程池执行异步代码
        long end = System.currentTimeMillis();
        System.out.println("-----------------------------------耗时:"+(end -start));
        System.out.println(future.get());  // get方法返回null,因为runAsync方法无返回值
        System.out.println("-----------------------------------");

    }

    public static void main(String[] args) {
        try {
            testSimpleCompletableFuture();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
